#include "tcp_receiver.hh"

// Dummy implementation of a TCP receiver

// For Lab 2, please replace with a real implementation that passes the
// automated checks run by `make check_lab2`.


using namespace std;
// SYN  C  A  T   S
//  0   1  2  3   4  seq
//      0  1  2   4

void TCPReceiver::segment_received(const TCPSegment &seg) {
    // 带有SYN
    if (seg.header().syn) {
        if (_syn)
            return;
        _syn = true;
        _isn = seg.header().seqno.raw_value();
        uint64_t index = unwrap(seg.header().seqno, WrappingInt32(_isn), 0);
        if (seg.header().fin)
            _fin = true;
        if (seg.length_in_sequence_space() > 1) 
            _reassembler.push_substring(string(seg.payload().str()), index, seg.header().fin);
    } else if (seg.header().fin) {
        if (!_syn || _fin)
            return;
        _fin = true;
        // seqno -> absolute_index -> stream_index
        uint64_t index = unwrap(seg.header().seqno, WrappingInt32(_isn), 0);
        // SYN占用了一个序号
        _reassembler.push_substring(string(seg.payload().str()), index - 1, true);
    } else {
        if (!_syn)
            return;
        uint64_t index = unwrap(seg.header().seqno, WrappingInt32(_isn), 0);
        // SYN占用了一个序号
        _reassembler.push_substring(string(seg.payload().str()), index - 1, false);
    }
}

optional<WrappingInt32> TCPReceiver::ackno() const {  
    if (_syn) {
        // stream_index -> absolute_index -> seqno
        uint32_t offset = 1;
        if (_fin && _reassembler.stream_out().input_ended())  
            offset++;
        return wrap(_reassembler.get_first_bytes() + offset, WrappingInt32(_isn)); 
    } else {
        return optional<WrappingInt32>{};
    }
}

size_t TCPReceiver::window_size() const { 
    return _capacity - (stream_out().bytes_written() - stream_out().bytes_read());   
}
